<template>
  <g @mousedown="mousedown">
    <path :d="d" :stroke-width="opt.lineWidth" :stroke="color" fill="none" :stroke-dasharray="dash" ref="line"/>
    <path :d="d" :stroke-width="opt.hoverLineWidth" stroke="rgba(0, 0, 0, 0)" fill="none" ref="lineBox" v-show="data.state === 1" @click="click" @mouseover="mouseover" @mouseout="mouseout"/>
  </g>
</template>

<script>
export default {
  props: {
    option: {},
    data: {
      default: () => {
        return {
          id: -1,
          head: { x: 0, y: 0 },
          tail: { x: 0, y: 0 },
          headNodeId: -1, // 头节点id，即上级节点的节点id
          tailNodeId: -1, // 尾节点id，即下级节点的节点id
          isSelected: false, // 是否被选中
          state: 0 // 是否创建完成
        }
      }
    }
  },
  data () {
    return {
      isMouseOver: false, // 鼠标是否移入
      headNode: { data: {} }, // 连线头部对应节点
      tailNode: { data: {} } // 连线尾部对应节点
    }
  },
  methods: {
    mouseover () {
      this.isMouseOver = true
    },
    mouseout () {
      this.isMouseOver = false
    },
    mousedown (event) {
      event.stopPropagation()
    },
    mouseup (event) {
      event.stopPropagation()
    },
    click (event) {
      // console.log('click')
      event.stopPropagation()
      if (this.data.state === 1) { // 创建完成后方可选中
        const hasChanged = this.$parent.singleSelect(this, event.shiftKey)
        if (hasChanged && this.$parent.opt.recordSelected) { // 如果状态改变 且 需要记录
          this.$parent.addHistory()
        }
      }
    },
    isSelected () {
      return this.data.isSelected
    },
    /**
     * 改变选中状态，返回true表示状态改变
     * @param  {Boolean} isSelected 选中状态
     * @return {Boolean} 选中状态是否改变
     * @author Jiangzhiwei
     * @time   2021-11-27T20:18:53+0800
     */
    setSelected (isSelected = true) {
      if (this.data.isSelected !== isSelected) { // 状态不同
        if (!isSelected) { // 取消选中
          // 判断连接的节点是否选中，如果有连接的节点选中，则无法取消选中
          if (this.headNode.data.isSelected || this.tailNode.data.isSelected) { // 有节点选中
            return false
          }
        }
        this.data.isSelected = isSelected
        return true
      }
      return false
    },
    /**
     * 标记线创建结束
     * @Author   Jiangzhiwei
     * @datetime 2021-10-21T10:32:25+0800
     */
    setOver () {
      this.data.state = 1
    },
    isOver () {
      return this.data.state === 1
    },
    remove () {
      this.$parent.removeLine(this.data.id)
    },
    /**
     * 更新连线的首尾节点
     * @author Jiangzhiwei
     * @time   2021-11-26T00:16:27+0800
     */
    updateNodes () {
      this.updateHeadNode()
      this.updateTailNode()
    },
    /**
     * 更新头节点
     * @author Jiangzhiwei
     * @time   2021-11-26T00:17:03+0800
     */
    updateHeadNode () {
      if (this.data.headNodeId !== -1) {
        const headNode = this.$parent.getNodeComp(this.data.headNodeId)
        // console.log('updateHeadNode:', this.data.headNodeId, headNode)
        if (this.headNode !== headNode) {
          this.headNode = headNode
        }
      }
    },
    /**
     * 更新尾节点
     * @author Jiangzhiwei
     * @time   2021-11-26T00:17:15+0800
     */
    updateTailNode () {
      if (this.data.tailNodeId !== -1) {
        const tailNode = this.$parent.getNodeComp(this.data.tailNodeId)
        if (this.tailNode !== tailNode) {
          this.tailNode = tailNode
        }
      }
    }
  },
  computed: {
    opt () {
      const option = {
        lineWidth: 3, // 线条宽度
        dashArray: 6, // 虚线数组
        hoverLineWidth: 20, // 用于显示移入效果的线条宽度
        color: '#8F7E3D', // 正常颜色
        hoverColor: '#E3BB36', // 移入颜色
        selectedColor: '#F5DA81' // 选中颜色
      }
      return Object.assign(option, this.option)
    },
    /**
     * 使用三次贝塞尔曲线绘制
     * @return   {String} 曲线路径
     * @Author   Jiangzhiwei
     * @datetime 2021-10-20T16:53:22+0800
     */
    d () {
      let hx, hy, tx, ty
      if (typeof this.headNode.data.isSelected !== 'undefined') {
        hx = this.headNode.getTail().x
        hy = this.headNode.getTail().y
      } else {
        hx = this.data.head.x
        hy = this.data.head.y
      }
      if (typeof this.tailNode.data.isSelected !== 'undefined') {
        tx = this.tailNode.getHead().x
        ty = this.tailNode.getHead().y
      } else {
        tx = this.data.tail.x
        ty = this.data.tail.y
      }
      const cx = (hx + tx) / 2
      // const cy = (hy + ty) / 2
      let dx = tx - hx
      if (dx < 0) { // 前在右，后在左
        dx = dx < -100 ? -100 : dx
        return `M ${hx} ${hy} C ${hx - dx} ${hy} ${tx + dx} ${ty} ${tx} ${ty}`
      } else { // 默认前在左，后在右
        return `M ${hx} ${hy} C ${cx} ${hy} ${cx} ${ty} ${tx} ${ty}`
      }
    },
    /**
     * 根据线条状态判断是实线还是虚线
     * @return   {Integer} 实线间距
     * @Author   Jiangzhiwei
     * @datetime 2021-10-20T16:52:09+0800
     */
    dash () {
      if (this.data.state === 0) {
        return this.opt.dashArray
      } else {
        return 0
      }
    },
    /**
     * 线条颜色 包括正常颜色、移入颜色、选中颜色
     * @return   {String} 颜色值
     * @Author   Jiangzhiwei
     * @datetime 2021-10-20T16:54:28+0800
     */
    color () {
      if (this.data.isSelected) {
        return this.opt.selectedColor
      } else if (this.isMouseOver) {
        return this.opt.hoverColor
      } else {
        return this.opt.color
      }
    },
    type () {
      return 'line'
    }
  },
  watch: {
    'data.headNodeId' () {
      this.updateHeadNode()
    },
    'data.tailNodeId' () {
      this.updateTailNode()
    },
    'headNode.data.isSelected' (val) {
      if (val) {
        this.data.isSelected = true
      }
    },
    'tailNode.data.isSelected' (val) {
      if (val) {
        this.data.isSelected = true
      }
    }
  },
  mounted () {
    this.updateNodes()
  }
}
</script>
